home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr46 / vfwdk.zip / VFWSDK.ZIP / SAMPLES / MSRLEC / MSRLEC.C < prev    next >
C/C++ Source or Header  |  1993-01-31  |  21KB  |  689 lines

  1. /****************************************************************************
  2.  *
  3.  *   msrlec.c
  4.  * 
  5.  *   MSRLEC is a sample installable compressor for AVI 1.0.  
  6.  *
  7.  *   Copyright (c) 1992-1993 Microsoft Corporation.  All Rights Reserved.
  8.  *
  9.  *    You have a royalty-free right to use, modify, reproduce and 
  10.  *    distribute the Sample Files (and/or any modified version) in 
  11.  *    any way you find useful, provided that you agree that 
  12.  *    Microsoft has no warranty obligations or liability for any 
  13.  *    Sample Application Files which are modified. 
  14.  *
  15.  ***************************************************************************/
  16.  
  17. #include <windows.h>
  18. #include <compddk.h>
  19.  
  20. #include "msrlec.h"
  21. #include "rle.h"
  22.  
  23. #define MODNAME         "RLEC"
  24. char    szDescription[] = "Microsoft RLE Sample Compressor";
  25. char    szName[]        = "MS-RLEC";
  26.  
  27. #define FOURCC_RLEC     mmioFOURCC('R','L','E','C')
  28.  
  29. #define TWOCC_DIB       aviTWOCC('d','b')
  30. #define TWOCC_RLE       aviTWOCC('d','c')
  31.  
  32. #define VERSION_RLEC    0x00010000      // 1.00
  33.  
  34. extern HANDLE ghModule ;
  35.  
  36. RLESTATE DefaultRleState = {FOURCC_RLEC};
  37.  
  38. /*****************************************************************************
  39.  *
  40.  * RleLoad() is called from the DRV_LOAD message.
  41.  *
  42.  * Tasks such as allocating global memory that is non-instance specific
  43.  * or initializing coprocessor hardware may be performed here.
  44.  *
  45.  * Our simple case needs none of this.
  46.  *
  47.  ****************************************************************************/
  48. BOOL NEAR PASCAL RleLoad()
  49. {
  50.     DPF("RleLoad()");
  51.     return TRUE;
  52. }
  53.  
  54. /*****************************************************************************
  55.  *
  56.  * RleFree() is called from the DRV_FREE message.
  57.  *
  58.  * It should totally reverse the effects of Load() in preparation for
  59.  * the DRV being removed from memory.
  60.  *
  61.  ****************************************************************************/
  62. void NEAR PASCAL RleFree()
  63. {
  64.     DPF("RleFree()");
  65. }
  66.  
  67. /*****************************************************************************
  68.  *
  69.  * RleOpen() is called from the ICM_OPEN message
  70.  *
  71.  * This message will be sent for a particular compress/decompress session.
  72.  * Our code must verify that we are indeed being called as a video
  73.  * compressor and create/initialize a state structure. The ICM will
  74.  * give us back the pointer to that structure on every message dealing
  75.  * with this session.
  76.  *
  77.  ****************************************************************************/
  78. PRLEINST NEAR PASCAL RleOpen(ICOPEN FAR * icinfo)
  79. {
  80.     PRLEINST pri;
  81.  
  82.     DPF("Open('%4.4ls', '%4.4ls')", (LPSTR)&icinfo->fccType, (LPSTR)&icinfo->fccHandler);
  83.  
  84.     //
  85.     // refuse to open if we are not being opened as a Video compressor
  86.     //
  87.     if (icinfo->fccType != ICTYPE_VIDEO)
  88.         return NULL;
  89.  
  90.     pri = (PRLEINST)LocalAlloc(LPTR, sizeof(RLEINST));
  91.  
  92.     if (pri)
  93.     {
  94.         RleSetState(pri, NULL, 0);
  95.     }
  96.     return pri;
  97. }
  98.  
  99. /*****************************************************************************
  100.  *
  101.  * Close() is called on the ICM_CLOSE message.
  102.  *
  103.  * This message is the complement to ICM_OPEN and marks the end
  104.  * of a compress/decompress session. We kill any in-progress operations
  105.  * (although this shouldn't be needed) and free our instance structure.
  106.  *
  107.  ****************************************************************************/
  108. DWORD NEAR PASCAL RleClose(PRLEINST pri)
  109. {
  110.     DPF("RleClose()");
  111.  
  112.     if (!pri)
  113.         return FALSE;
  114.  
  115.     LocalFree((LOCALHANDLE)pri);
  116.     return TRUE;
  117. }
  118.  
  119. /*****************************************************************************
  120.  *
  121.  * RleQueryAbout() and RleAbout() handle the ICM_ABOUT message.
  122.  *
  123.  * RleQueryAbout() returns TRUE to indicate we support an about box.
  124.  * RleAbout() displays the box.
  125.  *
  126.  ****************************************************************************/
  127. BOOL NEAR PASCAL RleQueryAbout(RLEINST * pinst)
  128. {
  129.     DPF("RleQueryAbout()");
  130.  
  131.     return TRUE;
  132. }
  133.  
  134. DWORD NEAR PASCAL RleAbout(RLEINST * pinst, HWND hwnd)
  135. {
  136.     DPF("RleAbout()");
  137.     MessageBox(hwnd,szDescription,szName,MB_OK|MB_ICONINFORMATION);
  138.     return ICERR_OK;
  139. }
  140.  
  141. /*****************************************************************************
  142.  *
  143.  * RleQueryConfigure() and RleConfigure() implement the ICM_CONFIGURE message.
  144.  *
  145.  * These functions put up a dialog that allows the user, if he so
  146.  * chooses, to modify the configuration portion of our state info.
  147.  * 
  148.  ****************************************************************************/
  149. BOOL NEAR PASCAL RleQueryConfigure(RLEINST * pinst)
  150. {
  151.     DPF("RleQueryConfigure()");
  152.     return FALSE;
  153. }
  154.  
  155. DWORD NEAR PASCAL RleConfigure(RLEINST * pinst, HWND hwnd)
  156. {
  157.     DPF("RleConfigure()");
  158.  
  159.     return ICERR_OK;
  160. }
  161.  
  162. /*****************************************************************************
  163.  *
  164.  * RleGetState() implements the ICM_GETSTATE message.
  165.  * 
  166.  * We copy our configuration information and return how many bytes it took.
  167.  *
  168.  ****************************************************************************/
  169. DWORD NEAR PASCAL RleGetState(PRLEINST pri, LPVOID pv, DWORD dwSize)
  170. {
  171.     DPF("RleGetState(%08lX, %ld)", pv, dwSize);
  172.  
  173.     if (pv == NULL || dwSize == 0)
  174.         return sizeof(RLESTATE);
  175.  
  176.     if (pri == NULL || dwSize < sizeof(RLESTATE))
  177.         return 0;
  178.  
  179.     *(LPRLESTATE)pv = pri->RleState;
  180.  
  181.     // return number of bytes copied
  182.     return sizeof(RLESTATE);
  183. }
  184.  
  185. /*****************************************************************************
  186.  *
  187.  * RleSetState() implements the ICM_SETSTATE message.
  188.  *
  189.  * The ICM is giving us configuration information saved by GetState()
  190.  * earlier.
  191.  *
  192.  ****************************************************************************/
  193. DWORD NEAR PASCAL RleSetState(PRLEINST pri, LPVOID pv, DWORD dwSize)
  194. {
  195.     DPF("RleSetState(%08lX, %ld)", pv, dwSize);
  196.  
  197.     if (pv == NULL || dwSize == 0)
  198.     {
  199.         pv = &DefaultRleState;
  200.         dwSize = sizeof(RLESTATE);
  201.     }
  202.  
  203.     if (pri == NULL || dwSize < sizeof(RLESTATE))
  204.         return 0;
  205.  
  206.     // make sure it is our state information.
  207.  
  208.     if (((LPRLESTATE)pv)->fccHandler != FOURCC_RLEC)
  209.         return 0;
  210.  
  211.     pri->RleState = *(LPRLESTATE)pv;
  212.  
  213.     // return number of bytes copied
  214.     return sizeof(RLESTATE);
  215. }
  216.  
  217. /*****************************************************************************
  218.  *
  219.  * RleGetInfo() implements the ICM_GETINFO message
  220.  *
  221.  * We just fill in the structure to tell the ICM what we can do. The flags
  222.  * (none of which this sample supports) mean the following :
  223.  *
  224.  * VIDCF_QUALITY - we support the quality variable. This means we look at
  225.  *                 dwQuality in the ICINFO structure when compressing and
  226.  *                 make a concious decision to trade quality for space.
  227.  *                 (higher values of dwQuality mean quality is more
  228.  *                 important). dwQuality is set by the ICM.
  229.  *
  230.  * VIDCF_TEMPORAL - We do interframe compression. In this algorithm, not
  231.  *                  every frame is a "key frame"; some frames depend on
  232.  *                  other frames to be generated. An example of this might
  233.  *                  be to store frame buffer differences until the
  234.  *                  differences are big enough to no longer make this
  235.  *                  worthwhile, then storing another complete frame and
  236.  *                  starting over. In this case, the complete frames that
  237.  *                  are stored are key frames and should be flagged as
  238.  *                  such.
  239.  *
  240.  * VIDCF_DRAW -     We will draw the decompressed image on our own. This is
  241.  *                  useful if the decompression is assisted by the video
  242.  *                  hardware.
  243.  *
  244.  ****************************************************************************/
  245. DWORD NEAR PASCAL RleGetInfo(PRLEINST pri, ICINFO FAR *icinfo, DWORD dwSize)
  246. {
  247.     DPF("RleGetInfo()");
  248.  
  249.     if (icinfo == NULL)
  250.         return sizeof(ICINFO);
  251.  
  252.     if (dwSize < sizeof(ICINFO))
  253.         return 0;
  254.  
  255.     icinfo->dwSize        = sizeof(ICINFO);
  256.     icinfo->fccType        = ICTYPE_VIDEO;
  257.     icinfo->fccHandler      = FOURCC_RLEC;
  258.     icinfo->dwFlags        = VIDCF_TEMPORAL;    // supports inter-frame
  259.     icinfo->dwVersion       = VERSION_RLEC;
  260.     icinfo->dwVersionICM    = ICVERSION;
  261.     lstrcpy(icinfo->szDescription, szDescription);
  262.     lstrcpy(icinfo->szName, szName);
  263.  
  264.     return sizeof(ICINFO);
  265. }
  266.  
  267. /*****************************************************************************
  268.  *
  269.  * RleCompressQuery() handles the ICM_COMPRESSQUERY message
  270.  *
  271.  * This message basically asks, "Can you compress this into this?"
  272.  *
  273.  * We look at the input and output bitmap info headers and determine
  274.  * if we can.
  275.  *
  276.  ****************************************************************************/
  277. LRESULT NEAR PASCAL RleCompressQuery(PRLEINST pri, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  278. {
  279.     DPF("CompressQuery()");
  280.  
  281.     //
  282.     // determine if the input DIB data is in a format we like.
  283.     //
  284.     if (lpbiIn == NULL ||
  285.         lpbiIn->biBitCount != 8 ||
  286.         lpbiIn->biCompression != BI_RGB)
  287.         return ICERR_BADFORMAT;
  288.  
  289.     //
  290.     //  are we being asked to query just the input format?
  291.     //
  292.     if (lpbiOut == NULL)
  293.         return ICERR_OK;
  294.  
  295.     //
  296.     // make sure we can handle the format to compress to also.
  297.     //
  298.     if (lpbiOut->biCompression != BI_RLE8 ||        // must be rle format
  299.         lpbiOut->biBitCount != 8 ||                 // must be 8bpp
  300.         lpbiOut->biWidth  != lpbiIn->biWidth ||     // must be 1:1 (no stretch)
  301.         lpbiOut->biHeight != lpbiIn->biHeight)
  302.         return ICERR_BADFORMAT;
  303.  
  304.     return ICERR_OK;
  305. }
  306.  
  307. /*****************************************************************************
  308.  *
  309.  * RleCompressGetFormat() implements ICM_GETFORMAT
  310.  *
  311.  * This message asks, "If I gave you this bitmap, what would you liek to
  312.  * compress it to?"
  313.  *
  314.  * If the output bitmap info header is NULL, we just return how big the
  315.  * header would be (header + palette, actually)
  316.  *
  317.  * Otherwise, we fill in the header, most importantly the biSizeImage.
  318.  * This field must contain an upper bound on the size of the compressed
  319.  * frame. A value that is too high here will result in inefficient
  320.  * memory allocation at compression time, but will not be reflected
  321.  * to the stored bitmap - the compression algorithm may chop biSizeImage
  322.  * down to the actual amount with no ill effects.
  323.  * 
  324.  ****************************************************************************/
  325. DWORD NEAR PASCAL RleCompressGetFormat(PRLEINST pri, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  326. {
  327.     DWORD dw;
  328.  
  329.     DPF("CompressGetFormat()");
  330.  
  331.     if (dw = (DWORD)RleCompressQuery(pri, lpbiIn, NULL))
  332.         return dw;
  333.  
  334.     dw = lpbiIn->biSize + (int)lpbiIn->biClrUsed * sizeof(RGBQUAD);
  335.  
  336.     //
  337.     // if lpbiOut == NULL then, return the size required to hold a output
  338.     // format
  339.     //
  340.     if (lpbiOut == NULL)
  341.         return dw;
  342.  
  343.     hmemcpy(lpbiOut, lpbiIn, dw);
  344.  
  345.     lpbiOut->biBitCount    = 8;
  346.     lpbiOut->biCompression = BI_RLE8;
  347.     lpbiOut->biSizeImage   = RleCompressGetSize(pri, lpbiIn, lpbiOut);
  348.  
  349.     return ICERR_OK;
  350. }
  351.  
  352. /*****************************************************************************
  353.  *
  354.  * RleCompressBegin() implements ICM_COMPRESSBEGIN
  355.  *
  356.  * We're about to start compressing, initialize coprocessor, etc.
  357.  * 
  358.  ****************************************************************************/
  359. LRESULT NEAR PASCAL RleCompressBegin(PRLEINST pri, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  360. {
  361.     LRESULT lResult;
  362.  
  363.     DPF("CompressBegin()");
  364.  
  365.     if (lResult = RleCompressQuery(pri, lpbiIn, lpbiOut))
  366.         return lResult;
  367.  
  368.     return ICERR_OK;
  369. }
  370.  
  371. /*****************************************************************************
  372.  *
  373.  * RleCompressGetSize() implements ICM_COMPRESS_GET_SIZE
  374.  *
  375.  * This function returns how much (upper bound) memory a compressed frame
  376.  * will take.
  377.  *
  378.  ****************************************************************************/
  379. DWORD NEAR PASCAL RleCompressGetSize(PRLEINST pri, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  380. {
  381.     int dx,dy;
  382.  
  383.     DPF("CompressGetSize()");
  384.  
  385.     //
  386.     // we assume RLE data will never be more than twice the size of a full frame.
  387.     //
  388.     dx = (int)lpbiIn->biWidth;
  389.     dy = (int)lpbiIn->biHeight;
  390.  
  391.     return (DWORD)dx * dy * 2;
  392. }
  393.  
  394. /*****************************************************************************
  395.  *
  396.  * RleCompress() implements ICM_COMPRESS
  397.  *
  398.  * Everything is set up; call the actual compression routine.
  399.  *
  400.  * Note:
  401.  *
  402.  * 1) We set the ckid in icinfo to a two-character code indicating how we
  403.  *    compressed. This code will be returned to us at decompress time to
  404.  *    allow us to pick a decompression algorithm to match. This is different
  405.  *    from icinfo->fccHandler, which tells which driver to use!
  406.  *
  407.  ****************************************************************************/
  408. LRESULT NEAR PASCAL RleCompress(PRLEINST pri, ICCOMPRESS FAR *icinfo, DWORD dwSize)
  409. {
  410.     LRESULT lResult;
  411.  
  412.     if (lResult = RleCompressQuery(pri, icinfo->lpbiInput, icinfo->lpbiOutput))
  413.         return lResult;
  414.  
  415.     DeltaFrame386(
  416.         icinfo->lpbiOutput,
  417.         icinfo->lpPrev,
  418.         icinfo->lpInput,
  419.         icinfo->lpOutput,
  420.         4);
  421.  
  422.     if (icinfo->lpckid)
  423.         *icinfo->lpckid = TWOCC_RLE;
  424.     
  425.     if (icinfo->lpdwFlags && icinfo->lpbiPrev == NULL)
  426.         *icinfo->lpdwFlags |= AVIIF_KEYFRAME;
  427.  
  428.     return ICERR_OK;
  429. }
  430.  
  431. /*****************************************************************************
  432.  *
  433.  * RleCompressEnd() is called on ICM_COMPRESS_END
  434.  *
  435.  * This function is a chance to flush buffers, deinit hardware, etc.
  436.  * after compressing a single frame.
  437.  *
  438.  ****************************************************************************/
  439. LRESULT NEAR PASCAL RleCompressEnd(PRLEINST pri)
  440. {
  441.     DPF("RleCompressEnd()");
  442.  
  443.     return ICERR_OK;
  444. }
  445.  
  446. /*****************************************************************************
  447.  *
  448.  * RleDecompressQuery() implements ICM_DECOMPRESS_QUERY
  449.  *
  450.  * See RleCompressQuery()
  451.  * 
  452.  ****************************************************************************/
  453. LRESULT NEAR PASCAL RleDecompressQuery(RLEINST * pri, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  454. {
  455.     DPF("RleDecompressQuery()");
  456.  
  457.     //
  458.     // determine if the input DIB data is in a format we like.
  459.     //
  460.     if (lpbiIn == NULL ||
  461.         lpbiIn->biBitCount != 8 ||
  462.         lpbiIn->biCompression != BI_RLE8)
  463.         return ICERR_BADFORMAT;
  464.  
  465.     //
  466.     //  are we being asked to query just the input format?
  467.     //
  468.     if (lpbiOut == NULL)
  469.         return ICERR_OK;
  470.  
  471.     //
  472.     // make sure we can handle the format to decompress too.
  473.     //
  474.     if (lpbiOut->biCompression != BI_RGB ||         // must be full dib
  475.         lpbiOut->biBitCount != 8 ||                 // must be 8bpp
  476.         lpbiOut->biWidth  != lpbiIn->biWidth ||     // must be 1:1 (no stretch)
  477.         lpbiOut->biHeight != lpbiIn->biHeight)
  478.         return ICERR_BADFORMAT;
  479.  
  480.     return ICERR_OK;
  481. }
  482.  
  483. /*****************************************************************************
  484.  *
  485.  * RleDecompressGetFormat() implements ICM_DECOMPRESS_GET_FORMAT
  486.  *
  487.  * See RleCompressGetFormat()
  488.  *
  489.  ****************************************************************************/
  490. DWORD NEAR PASCAL RleDecompressGetFormat(RLEINST * pri, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  491. {
  492.     DWORD dw;
  493.     int dx,dy;
  494.  
  495.     DPF("RleDecompressGetFormat()");
  496.  
  497.     if (dw = (DWORD)RleDecompressQuery(pri, lpbiIn, NULL))
  498.         return dw;
  499.  
  500.     dw = lpbiIn->biSize + (int)lpbiIn->biClrUsed * sizeof(RGBQUAD);
  501.  
  502.     //
  503.     // if lpbiOut == NULL then, return the size required to hold a output
  504.     // format
  505.     //
  506.     if (lpbiOut == NULL)
  507.         return dw;
  508.  
  509.     hmemcpy(lpbiOut, lpbiIn, dw);
  510.  
  511.     dx = (int)lpbiIn->biWidth;
  512.     dy = (int)lpbiIn->biHeight;
  513.  
  514.     lpbiOut->biBitCount    = 8;
  515.     lpbiOut->biCompression = BI_RGB;
  516.     lpbiOut->biSizeImage   = (DWORD)dy*(DWORD)((dx+3)&~3);
  517.  
  518.     return ICERR_OK;
  519. }
  520.  
  521. /*****************************************************************************
  522.  *
  523.  * RleDecompressGetPalette() implements ICM_GET_PALETTE
  524.  *
  525.  * This function has no Compress...() equivalent
  526.  *
  527.  * It is used to pull the palette from a frame in order to possibly do
  528.  * a palette change.
  529.  * 
  530.  ****************************************************************************/
  531. LRESULT NEAR PASCAL RleDecompressGetPalette(RLEINST * pinst, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  532. {
  533.     LRESULT lResult;
  534.  
  535.     DPF("RleDecompressGetPalette()");
  536.  
  537.     if (lResult = RleDecompressQuery(pinst, lpbiIn, lpbiOut))
  538.         return lResult;
  539.  
  540.     if (lpbiOut->biBitCount != 8)
  541.         return ICERR_BADFORMAT;
  542.  
  543.     if (lpbiIn->biClrUsed == 0)
  544.         lpbiIn->biClrUsed = 256;
  545.  
  546.     //
  547.     // return the 8bit palette used for decompression.
  548.     //
  549.     hmemcpy(
  550.         (LPBYTE)lpbiOut + (int)lpbiOut->biSize,
  551.         (LPBYTE)lpbiIn + (int)lpbiIn->biSize,
  552.         (int)lpbiIn->biClrUsed * sizeof(RGBQUAD));
  553.  
  554.     lpbiOut->biClrUsed = lpbiIn->biClrUsed;
  555.  
  556.     return ICERR_OK;
  557. }
  558.  
  559. /*****************************************************************************
  560.  ****************************************************************************/
  561. LRESULT NEAR PASCAL RleDecompressBegin(RLEINST * pri, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  562. {
  563.     LRESULT lResult;
  564.  
  565.     if (lResult = RleDecompressQuery(pri, lpbiIn, lpbiOut))
  566.         return lResult;
  567.  
  568.     return ICERR_OK;
  569. }
  570.  
  571. /*****************************************************************************
  572.  *
  573.  * RleDecompressBegin() implements ICM_DECOMPRESS_BEGIN
  574.  *
  575.  * See RleCompressBegin()
  576.  * 
  577.  ****************************************************************************/
  578. LRESULT NEAR PASCAL DecompressBegin(RLEINST * pinst, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  579. {
  580.     LRESULT lResult;
  581.  
  582.     DPF("RleDecompressBegin()");
  583.  
  584.     if (lResult = RleDecompressQuery(pinst, lpbiIn, lpbiOut))
  585.         return lResult;
  586.  
  587.     return ICERR_OK;
  588. }
  589.  
  590. /*****************************************************************************
  591.  *
  592.  * RleDecompress() implements ICM_DECOMPRESS
  593.  *
  594.  * See RleDecompressBegin()
  595.  * 
  596.  ****************************************************************************/
  597. LRESULT NEAR PASCAL RleDecompress(RLEINST * pri, ICDECOMPRESS FAR *icinfo, DWORD dwSize)
  598. {
  599.     PlayRle(icinfo->lpbiOutput, icinfo->lpOutput, icinfo->lpInput);
  600.  
  601.     return ICERR_OK;
  602. }
  603.  
  604. /*****************************************************************************
  605.  *
  606.  * RleDecompressEnd() implements ICM_DECOMPRESS_END
  607.  *
  608.  * See RleCompressEnd()
  609.  *
  610.  ****************************************************************************/
  611. LRESULT NEAR PASCAL RleDecompressEnd(RLEINST * pri)
  612. {
  613.     DPF("RleDecompressEnd()");
  614.  
  615.     return ICERR_OK;
  616. }
  617.  
  618. //////////////////////////////////////////////////////////////////////////////
  619. //
  620. // ICM_DRAW routines.
  621. //
  622. //////////////////////////////////////////////////////////////////////////////
  623.  
  624. /*****************************************************************************
  625.  *
  626.  * RleDrawQuery() implements ICM_DRAW_QUERY
  627.  *
  628.  ****************************************************************************/
  629. BOOL NEAR PASCAL RleDrawQuery(RLEINST * pinst, LPBITMAPINFOHEADER lpbiInput)
  630. {
  631.     return FALSE;
  632. }
  633.  
  634. /*****************************************************************************
  635.  ****************************************************************************/
  636. LRESULT NEAR PASCAL RleDrawBegin(RLEINST * pri,ICDRAWBEGIN FAR *icinfo, DWORD dwSize)
  637. {
  638.     return ICERR_UNSUPPORTED;
  639. }
  640.  
  641. /*****************************************************************************
  642.  ****************************************************************************/
  643. LRESULT NEAR PASCAL RleDraw(RLEINST * pri, ICDRAW FAR *icinfo, DWORD dwSize)
  644. {
  645.     return ICERR_UNSUPPORTED;
  646. }
  647.  
  648. /*****************************************************************************
  649.  ****************************************************************************/
  650. LRESULT NEAR PASCAL RleDrawEnd(RLEINST * pri)
  651. {
  652.     return ICERR_UNSUPPORTED;
  653. }
  654.  
  655. /*****************************************************************************
  656.  *
  657.  * dprintf() is called by the DPF macro if DEBUG is defined at compile time.
  658.  *
  659.  * The messages will be send to COM1: like any debug message. To 
  660.  * enable debug output, add the following to WIN.INI :
  661.  *
  662.  * [debug]
  663.  * MSRLEC=1
  664.  *
  665.  ****************************************************************************/
  666.  
  667. #ifdef DEBUG
  668.  
  669. void FAR cdecl dprintf(LPSTR szFormat, ...)
  670. {
  671.     char ach[128];
  672.  
  673.     static BOOL fDebug = -1;
  674.  
  675.     if (fDebug == -1)
  676.         fDebug = GetProfileInt("Debug", MODNAME, FALSE);
  677.  
  678.     if (!fDebug)
  679.         return;
  680.  
  681.     lstrcpy(ach, MODNAME ": ");
  682.     wvsprintf(ach+lstrlen(ach),szFormat,(LPSTR)(&szFormat+1));
  683.     lstrcat(ach, "\r\n");
  684.  
  685.     OutputDebugString(ach);
  686. }
  687.  
  688. #endif
  689.